package com.wolfking.converter.transform.extend;

import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import com.wolfking.converter.transform.AbstractExtendTransform;
import com.wolfking.converter.util.ConverterSpringContext;
import com.wolfking.jeesite.entity.Dict;
import com.wolfking.jeesite.service.DictService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Slf4j
public class DictTransform extends AbstractExtendTransform<String> {

    private final String type;

    public DictTransform(){
        this("");
    }

    public DictTransform(String arg) {
        this.type = arg;
    }

    @SuppressWarnings("all")
    private static final LoadingCache<String, Map<String, String>> dictCache = CacheBuilder.newBuilder().expireAfterWrite(10, TimeUnit.SECONDS)
            .maximumSize(1000)
            .concurrencyLevel(100)
            .build(new CacheLoader<String, Map<String, String>>() {
                @Override
                public Map<String, String> load(String dict) {
                    DictService bean = ConverterSpringContext.getBean(DictService.class);
                    List<Dict> dictList = bean.getByType(dict);
                    return dictList.stream().collect(Collectors.toMap(Dict::getValue, Dict::getLabel, (e1, e2) -> e1));
                }
            });

    @Override
    public String transform(Object value) throws Exception {
        if (Objects.isNull(value)) {
            return "";
        } else {
            String toStr = value.toString();
            if (StringUtils.isNotBlank(toStr)) {
                try {
                    return dictCache.get(type).getOrDefault(toStr, toStr);
                } catch (Exception e) {
                    log.warn("", e);
                }
            }
            return toStr;
        }
    }

    public static void main(String[] args) {
        String json = "{\n" +
                "\t\"100\": \"工商银行\",\n" +
                "\t\"101\": \"建设银行\",\n" +
                "\t\"102\": \"光大银行\",\n" +
                "\t\"103\": \"民生银行\",\n" +
                "\t\"104\": \"邮政储蓄银行\",\n" +
                "\t\"105\": \"招商银行\",\n" +
                "\t\"106\": \"农业银行\",\n" +
                "\t\"107\": \"北京银行\",\n" +
                "\t\"108\": \"交通银行\",\n" +
                "\t\"109\": \"广发银行\",\n" +
                "\t\"110\": \"中国银行\",\n" +
                "\t\"111\": \"平安银行\",\n" +
                "\t\"112\": \"兴业银行\",\n" +
                "\t\"113\": \"中信银行\",\n" +
                "\t\"114\": \"恒丰银行\",\n" +
                "\t\"115\": \"华夏银行\",\n" +
                "\t\"116\": \"浦发银行\",\n" +
                "\t\"117\": \"深圳发展银行\",\n" +
                "\t\"118\": \"重庆银行\",\n" +
                "\t\"119\": \"上海银行\"\n" +
                "}";

        @SuppressWarnings("all")
        Map<String, String> map = new Gson().fromJson(json, new TypeToken<Map<String, String>>() {
        }.getType());

        String type = "bankCode";

        String desc = "银行编码";

        String sql = "INSERT INTO `sys_dict`(`type`,`value`,`label`,`description`,`sort`,`create_by`,\t`create_time`,`update_by`,`update_time`,`remarks`,`del_flag`,`version`) \n" +
                "VALUES ('%s', '%s', '%s', '%s', 10, 1, now(), 1, now(), '', '0', 6);";

//        String collect = Arrays.stream(RemittanceConfirmOperateType.values()).map(f -> String.format(sql, type, f.name(), f, desc))
//            .collect(Collectors.joining("\n"));
//        System.out.println(collect);

        String collect = map.entrySet().stream().map(e -> String.format(sql, type, e.getKey(), e.getValue(), desc))
                .collect(Collectors.joining("\n"));
        System.out.println(collect);

        json = "{\n" +
                "  \"defineKey\": \"withhold_balance\",\n" +
                "  \"underLineToCamel\": \"true\",\n" +
                "  \"sqlDescribe\": \"划扣到余额\",\n" +
                "  \"id\": \"\",\n" +
                "  \"paramVerify\": \"\",\n" +
                "  \"dataSource\": \"proxy\",\n" +
                "  \"sqlBase64\": \"select \\r\\n\\tu.partner_user_id as `业务用户ID`,\\r\\n\\tu.user_name as `姓名`,\\r\\n\\tu.mobile as `手机号`,\\r\\n\\tu.id_card as `身份证`,\\r\\n\\tuc.amount as `金额`,\\r\\n\\tuc.bank_card as `银行卡号`,\\r\\n\\tuc.pay_channel as `渠道`,\\r\\n\\tuc.pay_subject as `主体`,\\r\\n\\tDATE_FORMAT(uc.partner_request_time,'%m-%d %T') as `业务请求时间`,\\r\\n  DATE_FORMAT(uc.payment_confirm_time,'%m-%d %T') as `支付确认时间`,\\r\\n\\tTIMESTAMPDIFF(SECOND,uc.partner_request_time,COALESCE(uc.partner_call_time,uc.payment_confirm_time,uc.update_time)) as `耗时`,\\r\\n\\tCASE WHEN uc.payment_confirm_status = -1 THEN uc.pay_message\\r\\n\\t\\t   WHEN uc.payment_confirm_status = 2 THEN '成功'\\r\\n\\t\\t\\t ELSE '处理中' END as `支付状态`,\\r\\n\\tCASE WHEN uc.payment_confirm_status <> 2 THEN '支付失败'\\r\\n\\t\\t\\t WHEN uc.account_report_status = -1 THEN  '失败'\\r\\n\\t\\t   WHEN uc.payment_confirm_status = 2 THEN '成功'\\r\\n\\t\\t\\t ELSE '处理中' END as `上报账务状态`,\\r\\n\\tDATE_FORMAT(uc.account_report_time,'%m-%d %T') as `上报账务时间`,\\r\\n\\tDATE_FORMAT(uc.partner_call_time,'%m-%d %T') as `回调业务时间`,\\r\\n\\tuc.proxy_serial_no as `代理序列号`,\\r\\n\\tuc.partner_charge_no as `业务序列号`,\\r\\n\\tuc.pay_serial_no as `支付订单号`,\\r\\n\\tDATE_FORMAT(uc.create_time,'%Y-%m-%d %H:%m') as `创建时间`,\\r\\n  DATE_FORMAT(uc.update_time,'%Y-%m-%d %H:%m') as `更新时间`,\\r\\n  (select GROUP_CONCAT(j.machine_status,'(',j.execute_times,'-',j.job_status,')') from job j where j.proxy_serial_no = uc.proxy_serial_no ORDER BY j.id ASC) as `jobs`\\r\\nfrom user_charge uc \\r\\nINNER JOIN `user` u on uc.user_id = u.id and u.partner_id in (1,2,3,4,5,6,7,8)\\r\\nwhere uc.partner_id in (1,2,3,4,5,6,7,8)\\r\\n\\t{{create_time_start}}\\r\\n\\t{{create_time_end}}\\r\\n    {{proxy_serial_no}}\\r\\n\\t{{partner_charge_no}}\\r\\n\\t{{partner_user_id}}\\r\\nORDER BY uc.create_time DESC\\r\\nlimit :pageNum,:pageSize;\",\n" +
                "  \"countSqlBase64\": \"select \\r\\n     count(1)  \\r\\nfrom user_charge uc \\r\\nINNER JOIN `user` u on uc.user_id = u.id and u.partner_id in (1,2,3,4,5,6,7,8)\\r\\nwhere uc.partner_id in (1,2,3,4,5,6,7,8)\\r\\n\\t{{create_time_start}}\\r\\n\\t{{create_time_end}}\\r\\n        {{proxy_serial_no}}\\r\\n\\t{{partner_charge_no}}\\r\\n\\t{{partner_user_id}}\",\n" +
                "  \"version\": \"\",\n" +
                "  \"allowEmptyParamQuery\": \"false\"\n" +
                "}\n";

        JsonElement jsonElement = JsonParser.parseString(json);
        String sqlBase64 = jsonElement.getAsJsonObject().get("sqlBase64").getAsString();
        System.out.println(sqlBase64);
    }
}